/**
 * 
 */
package br.edu.ufcg.compiladores.brasigol.semantico;

import br.edu.ufcg.compiladores.brasigol.exceptions.InvalidDataType;
import br.edu.ufcg.compiladores.brasigol.exceptions.MisturaDeTiposException;

/**
 * @author Marcelo Emanoel
 * 
 */
public enum TipoDeDado {
	TEXTO{
		TipoDeDado getTipoResultante(TipoDeDado tipo)
		throws MisturaDeTiposException{
			return TEXTO;
		}

		boolean isValorValido(String valor){
			return true;
		}
	},
	INTEIRO {
		TipoDeDado getTipoResultante(TipoDeDado tipo)
				throws MisturaDeTiposException {
			if (tipo.equals(INTEIRO))
				return tipo;
			throw new MisturaDeTiposException(tipo,INTEIRO);
		}

		boolean isValorValido(String valor) {
			try {
				Integer.parseInt(valor);
				return true;
			} catch (Exception e) {
				return false;
			}
		}
	},
	BOOLEANO {
		TipoDeDado getTipoResultante(TipoDeDado tipo)
				throws MisturaDeTiposException {
			if(tipo.equals(BOOLEANO))
				return tipo;
			throw new MisturaDeTiposException(tipo,BOOLEANO);
		}
		boolean isValorValido(String valor) {
			return (valor.equalsIgnoreCase("VERDADE") || valor.equalsIgnoreCase("FALSO")); 
		}
	};
	abstract TipoDeDado getTipoResultante(TipoDeDado tipo) throws MisturaDeTiposException;
	abstract boolean isValorValido(String valor);
	/**
	 * @param tipo
	 * @return
	 */
	public static TipoDeDado getTipo(String tipo) {
		if (tipo.equalsIgnoreCase("INTEIRO")) {
			return INTEIRO;
		}
		if (tipo.equalsIgnoreCase("TEXTO")){
			return TEXTO;
		}
		if (tipo.equalsIgnoreCase("BOOLEANO")){
			return BOOLEANO;
		}
		throw new InvalidDataType(tipo);

	}

	/**
	 * @param lexeme
	 * @return
	 */
	public static TipoDeDado descobreTipo(String lexeme) {
		if (lexeme.startsWith("\"")){
				return TEXTO;
		}
		for (TipoDeDado tipo : values()) {
			if (!tipo.equals(TEXTO) && tipo.isValorValido(lexeme))
				return tipo;
		}
		throw new InvalidDataType("", lexeme);
	}
}